package sundeepk.github.com.sample;


import com.github.sundeepk.compactcalendarview.CompactCalendarView;
import com.github.sundeepk.compactcalendarview.LogUtil;
import com.github.sundeepk.compactcalendarview.ResourceTable;
import com.github.sundeepk.compactcalendarview.domain.Event;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * CompactCalendarTab
 */
public class CompactCalendarTab extends DependentLayout {
    private static final String TAG = "MainAbility";
    private final Calendar currentCalender = Calendar.getInstance(Locale.getDefault());
    private SimpleDateFormat dateFormatForDisplaying = new
            SimpleDateFormat("dd-M-yyyy hh:mm:ss a", Locale.getDefault());
    private final SimpleDateFormat dateFormatForMonth = new
            SimpleDateFormat("MMM - yyyy", Locale.getDefault());
    private boolean shouldShow = false;
    private final CompactCalendarView compactCalendarView;
    private Text toolbar;

    public CompactCalendarTab(Context context) {
        this(context, null);
    }

    public CompactCalendarTab(Context context, AttrSet attrSet) {
        super(context, attrSet);
        Component component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_main_tab, this, false);
        final List<String> mutableBookings = new ArrayList<>();

        final ListContainer bookingsListView = (ListContainer) component
                .findComponentById(ResourceTable.Id_bookings_listview);

        SampleItemProvider adapter = new SampleItemProvider(mutableBookings);
        bookingsListView.setItemProvider(adapter);
        compactCalendarView = (CompactCalendarView) component
                .findComponentById(ResourceTable.Id_compactcalendar_view);

        compactCalendarView.setUseThreeLetterAbbreviation(false);
        compactCalendarView.setFirstDayOfWeek(Calendar.MONDAY);
        compactCalendarView.setIsRtl(false);
        compactCalendarView.displayOtherMonthDays(false);
        loadEvents();
        loadEventsForYear(2017);
        compactCalendarView.invalidate();

        logEventsByMonth(compactCalendarView);

        // below line will display Sunday as the first day of the week

        // disable scrolling calendar

        // show days from other months as greyed out days

        // show Sunday as first day of month

        // set initial title

        // set title on calendar scroll
        compactCalendarView.setListener(new CompactCalendarView.CompactCalendarViewListener() {
            @Override
            public void onDayClick(Date dateClicked) {
                toolbar.setText(dateFormatForMonth.format(dateClicked));
                List<Event> bookingsFromMap = compactCalendarView.getEvents(dateClicked);
                if (bookingsFromMap != null) {
                    LogUtil.loge(TAG, bookingsFromMap.toString());
                    mutableBookings.clear();
                    for (Event booking : bookingsFromMap) {
                        mutableBookings.add((String) booking.getData());
                    }
                    adapter.notifyDataChanged();
                }
            }

            @Override
            public void onMonthScroll(Date firstDayOfNewMonth) {
                toolbar.setText(dateFormatForMonth.format(firstDayOfNewMonth));
            }
        });
        final Button showPreviousMonthBut = (Button) component
                .findComponentById(ResourceTable.Id_prev_button);
        showPreviousMonthBut.setClickedListener(view -> compactCalendarView.scrollLeft());
        final Button showNextMonthBut = (Button) component
                .findComponentById(ResourceTable.Id_next_button);
        showNextMonthBut.setClickedListener(view -> compactCalendarView.scrollRight());

        final Component.ClickedListener showCalendarOnClickLis = getCalendarShowLis();
        final Button slideCalendarBut = (Button) component
                .findComponentById(ResourceTable.Id_slide_calendar);
        slideCalendarBut.setClickedListener(showCalendarOnClickLis);

        final Component.ClickedListener exposeCalendarListener = getCalendarExposeLis();
        final Button showCalendarWithAnimationBut = (Button) component
                .findComponentById(ResourceTable.Id_show_with_animation_calendar);
        showCalendarWithAnimationBut.setClickedListener(exposeCalendarListener);

        compactCalendarView.setAnimationListener(new CompactCalendarView.CompactCalendarAnimationListener() {
            @Override
            public void onOpened() {
            }

            @Override
            public void onClosed() {
            }
        });

        final Button setLocaleBut = (Button) component.findComponentById(ResourceTable.Id_set_locale);
        setLocaleBut.setClickedListener(view -> {
            Locale locale = Locale.FRANCE;
            dateFormatForDisplaying = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a", locale);
            TimeZone timeZone = TimeZone.getTimeZone("Europe/Paris");
            dateFormatForDisplaying.setTimeZone(timeZone);
            dateFormatForMonth.setTimeZone(timeZone);
            compactCalendarView.setLocale(timeZone, locale);
            compactCalendarView.setUseThreeLetterAbbreviation(false);
            loadEvents();
            loadEventsForYear(2017);
            logEventsByMonth(compactCalendarView);
        });
        final Button removeAllEventsBut = (Button) component
                .findComponentById(ResourceTable.Id_remove_all_events);
        removeAllEventsBut.setClickedListener(v -> compactCalendarView.removeAllEvents());

        // uncomment below to show indicators above small indicator events
        // compactCalendarView.shouldDrawIndicatorsBelowSelectedDays(true);

        // uncomment below to open onCreate
        // openCalendarOnCreate(v);
        addComponent(component);
    }

    private Component.ClickedListener getCalendarShowLis() {
        return view -> {
            if (shouldShow) {
                compactCalendarView.showCalendar();
            } else {
                compactCalendarView.hideCalendar();
            }
            shouldShow = !shouldShow;
        };
    }

    private Component.ClickedListener getCalendarExposeLis() {
        return view -> {
            if (!compactCalendarView.isAnimating()) {
                if (shouldShow) {
                    compactCalendarView.showCalendarWithAnimation();
                } else {
                    compactCalendarView.hideCalendarWithAnimation();
                }
                shouldShow = !shouldShow;
            }
        };
    }

    private void openCalendarOnCreate(Component component) {
        final DependentLayout layout = (DependentLayout) component.findComponentById(ResourceTable.Id_main_content);
        ComponentTreeObserver vto = layout.getComponentTreeObserver();
        vto.addGlobalFocusUpdatedListener(new ComponentTreeObserver.GlobalFocusUpdatedListener() {
            @Override
            public void onGlobalFocusUpdated(Component component, Component component1) {
                layout.getComponentTreeObserver().removeGlobalFocusUpdatedListener(this);
                compactCalendarView.showCalendarWithAnimation();
            }
        });
    }

    private void loadEvents() {
        addEvents(-1, -1);
        addEvents(Calendar.DECEMBER, -1);
        addEvents(Calendar.AUGUST, -1);
    }

    private void loadEventsForYear(int year) {
        addEvents(Calendar.DECEMBER, year);
        addEvents(Calendar.AUGUST, year);
    }

    private void logEventsByMonth(CompactCalendarView compactCalendarView) {
        currentCalender.setTime(new Date());
        currentCalender.set(Calendar.DAY_OF_MONTH, 1);
        currentCalender.set(Calendar.MONTH, Calendar.AUGUST);
        List<String> dates = new ArrayList<>();
        for (Event event : compactCalendarView.getEventsForMonth(new Date())) {
            dates.add(dateFormatForDisplaying.format(event.getTimeInMillis()));
        }
        LogUtil.loge(TAG, "Events for Aug with simple date formatter: " + dates);
        LogUtil.loge(TAG, "Events for Aug month using default local and timezone: " +
                compactCalendarView.getEventsForMonth(currentCalender.getTime()));
    }

    private void addEvents(int month, int year) {
        currentCalender.setTime(new Date());
        currentCalender.set(Calendar.DAY_OF_MONTH, 1);
        Date firstDayOfMonth = currentCalender.getTime();
        for (int i = 0; i < 6; i++) {
            currentCalender.setTime(firstDayOfMonth);
            if (month > -1) {
                currentCalender.set(Calendar.MONTH, month);
            }
            if (year > -1) {
                currentCalender.set(Calendar.ERA, GregorianCalendar.AD);
                currentCalender.set(Calendar.YEAR, year);
            }
            currentCalender.add(Calendar.DATE, i);
            setToMidnight(currentCalender);
            long timeInMillis = currentCalender.getTimeInMillis();
            List<Event> events = getEvents(timeInMillis, i);

            compactCalendarView.addEvents(events);
        }
    }

    private List<Event> getEvents(long timeInMillis, int day) {
        if (day < 2) {
            return Collections.singletonList(new Event
                    (Color.argb(255, 169, 68, 65), timeInMillis,
                            "Event at " + new Date(timeInMillis)));
        } else if (day > 2 && day <= 4) {
            return Arrays.asList(
                    new Event(Color.argb(255, 169, 68, 65),
                            timeInMillis, "Event at " + new Date(timeInMillis)),
                    new Event(Color.argb(255, 100, 68, 65),
                            timeInMillis, "Event 2 at " + new Date(timeInMillis)));
        } else {
            return Arrays.asList(
                    new Event(Color.argb(255, 169, 68, 65),
                            timeInMillis, "Event at " + new Date(timeInMillis)),
                    new Event(Color.argb(255, 100, 68, 65),
                            timeInMillis, "Event 2 at " + new Date(timeInMillis)),
                    new Event(Color.argb(255, 70, 68, 65),
                            timeInMillis, "Event 3 at " + new Date(timeInMillis)));
        }
    }

    private void setToMidnight(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
    }

    /**
     * 设置标题。
     *
     * @param tvTitle 标题。
     */
    public void setTitle(final Text tvTitle) {
        this.toolbar = tvTitle;
        toolbar.setText(dateFormatForMonth.format(compactCalendarView.getFirstDayOfCurrentMonth()));
    }

    /**
     * setViewRefresh
     */
    public void setViewRefresh() {
        compactCalendarView.invalidate();
    }
}